package com.ssy.lingxi.product.serviceImpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.product.api.model.request.warehouse.InventoryListRequest;
import com.ssy.lingxi.product.api.model.request.warehouse.InventorySafetyUpdateRequest;
import com.ssy.lingxi.product.api.model.request.warehouse.QueryGoodsInventoryRequest;
import com.ssy.lingxi.product.api.model.request.warehouse.QueryInventoryByItemNoRequest;
import com.ssy.lingxi.product.api.model.response.warehouse.InventoryListResponse;
import com.ssy.lingxi.product.api.model.response.warehouse.InvoicesListResponse;
import com.ssy.lingxi.product.api.model.response.warehouse.QueryGoodsInventoryReesponse;
import com.ssy.lingxi.product.api.model.response.warehouse.QueryInventoryByItemNoResponse;
import com.ssy.lingxi.product.common.constant.StateConstant;
import com.ssy.lingxi.product.entity.material.MaterialGroup;
import com.ssy.lingxi.product.entity.warehouse.Inventory;
import com.ssy.lingxi.product.entity.warehouse.Invoices;
import com.ssy.lingxi.product.entity.warehouse.InvoicesType;
import com.ssy.lingxi.product.entity.warehouse.Warehouse;
import com.ssy.lingxi.product.repository.material.MaterialGroupRepository;
import com.ssy.lingxi.product.repository.warehouse.InventoryRepository;
import com.ssy.lingxi.product.repository.warehouse.WarehouseRepository;
import com.ssy.lingxi.product.service.InventoryService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 库存管理
 *
 * @author wrc
 * @date 2020/6/30
 */
@Service
public class InventoryServiceImpl implements InventoryService {

    @Resource
    InventoryRepository inventoryRepository;

    @Resource
    WarehouseRepository warehouseRepository;

    @Resource
    MaterialGroupRepository materialGroupRepository;

    /**
     * 查询库存列表
     *
     * @param request
     * @author wrc
     * @date 2020/6/29
     */
    @Override
    public Wrapper<PageData<InventoryListResponse>> inventoryList(InventoryListRequest request, UserLoginCacheDTO sysUser) {
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("updateTime").descending());
        Page<Inventory> pageList = inventoryRepository.findAll((Specification<Inventory>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("memberId"), sysUser.getMemberId()));
            predicateList.add(cb.equal(root.get("memberRoleId"), sysUser.getMemberRoleId()));

            if (StringUtils.isNotEmpty(request.getGoodsNo())) {
                predicateList.add(cb.like(root.get("goodsNo"), "%" + request.getGoodsNo() + "%"));
            }

            if (StringUtils.isNotEmpty(request.getGoodsName())) {
                predicateList.add(cb.like(root.get("goodsName"), "%" + request.getGoodsName() + "%"));
            }

            if (StringUtils.isNotEmpty(request.getSpecifications())) {
                predicateList.add(cb.like(root.get("specifications"), "%" + request.getSpecifications() + "%"));
            }

            if (StringUtils.isNotEmpty(request.getCategory())) {
                predicateList.add(cb.like(root.get("category"), "%" + request.getCategory() + "%"));
            }

            if (Objects.nonNull(request.getMaterialGroupId())) {
                predicateList.add(cb.equal(root.get("materialGroupId"), request.getMaterialGroupId()));
            }

            if (StringUtils.isNotEmpty(request.getBrand())) {
                predicateList.add(cb.like(root.get("brand"), "%" + request.getBrand() + "%"));
            }

            if (Objects.nonNull(request.getWarehouseId())) {
                predicateList.add(cb.equal(root.get("warehouseId"), request.getWarehouseId()));
            }


            Predicate[] p = new Predicate[predicateList.size()];
            return query.where(predicateList.toArray(p)).getRestriction();
        }, page);

        List<InventoryListResponse> resultList = pageList.stream().map(inventory -> {
            InventoryListResponse response = new InventoryListResponse();
            BeanUtils.copyProperties(inventory, response);
            response.setWarehouseName(Optional.ofNullable(warehouseRepository.findById(inventory.getWarehouseId()).map(Warehouse::getName).orElse("")).orElse(""));
            response.setGoodsGroup(inventory.getMaterialGroupId() != null ? materialGroupRepository.findById(inventory.getMaterialGroupId()).map(MaterialGroup::getName).orElse("") : "");
            return response;
        }).collect(Collectors.toList());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), resultList));
    }

    /**
     * 单个/批量调整安全库存
     *
     * @author wrc
     * @date 2020/6/30
     */
    @Transactional
    @Override
    public Wrapper<Void> inventorySafetyUpdate(InventorySafetyUpdateRequest request) {
        List<Inventory> inventorys = inventoryRepository.findAllByIdIn(request.getIds());
        if (CollectionUtil.isEmpty(inventorys)) {
            return Wrapper.fail(ResponseCode.RECORDS_DON_T_EXIST);
        }
        inventorys.stream().forEach(inventory -> inventory.setSafeInventoryCount(request.getSafetyInvoices()));
        inventoryRepository.saveAll(inventorys);
        return Wrapper.success();
    }

    /**
     * 查询仓库货品库存
     *
     * @author wrc
     * @date 2020/6/30
     */
    @Override
    public QueryGoodsInventoryReesponse queryGoodsInventory(QueryGoodsInventoryRequest request) {
        Inventory invoices = new Inventory();
        BeanUtils.copyProperties(request, invoices);
        Example<Inventory> example = Example.of(invoices);
        List<Inventory> all = inventoryRepository.findAll(example);
        QueryGoodsInventoryReesponse queryGoodsInvoicesReesponse = new QueryGoodsInventoryReesponse();
        if (!CollectionUtils.isEmpty(all)) {
            Inventory inventory = all.get(0);
            queryGoodsInvoicesReesponse.setInvoices(inventory.getInvoicesCount());
            queryGoodsInvoicesReesponse.setUnit(inventory.getUnit());
        }
        return queryGoodsInvoicesReesponse;
    }

    /**
     * 根据仓库和货号ID查询库存
     *
     * @author wrc
     * @date 2020/8/7
     */
    @Override
    public Wrapper<QueryInventoryByItemNoResponse> queryInventoryByItemNo(QueryInventoryByItemNoRequest request) {
        Inventory byItemIdAndWarehouseIdEquals = inventoryRepository.findByGoodsIdAndWarehouseIdEquals(request.getItemId(), request.getWarehouseId());
        QueryInventoryByItemNoResponse queryInventoryByItemNoResponse = new QueryInventoryByItemNoResponse();
        //queryInventoryByItemNoResponse.setInventory(null == byItemIdAndWarehouseIdEquals ? 0.0 : byItemIdAndWarehouseIdEquals.getInventoryCount());
        return Wrapper.success(queryInventoryByItemNoResponse);
    }
}
